import UIKit

var greeting = "Hello, playground"

// MARK:赋值 =，+=，-=，*=，/=
let i1 = 1
var i2 = i1
i2 = 2
print(i2) // 2

i2 += 1
print(i2) // 3

i2 -= 2
print(i2) // 1

i2 *= 10
print(i2) // 10

i2 /= 2
print(i2) // 5

// MARK:计算符 +，-，*，/，%
let i1_ = 1
let i2_ = i1_
print((i1_ + i2_ - 1) * 10 / 2 % 3) // 2
print("i" + "1") // i1

// 一元运算符
print(-i1_) // -1

// MARK:比较运算符 ==，>
// 遵循 Equatable 协议可以使用 == 和 != 来判断是否相等
print(1 > 2) // false

struct S: Equatable {
    var p1: String
    var p2: Int
}
let s1 = S(p1: "one", p2: 1)
let s2 = S(p1: "two", p2: 2)
let s3 = S(p1: "one", p2: 2)
let s4 = S(p1: "one", p2: 1)

print(s1 == s2) // false
print(s1 == s3) // false
print(s1 == s4) // true

//类需要实现 == 函数
class C: Equatable {
    var p1: String
    var p2: Int
    init(p1: String, p2: Int) {
        self.p1 = p1
        self.p2 = p2
    }
    
    static func == (l: C, r: C) -> Bool {
        return l.p1 == r.p1 && l.p2 == r.p2
    }
}

let c1 = C(p1: "one", p2: 1)
let c2 = C(p1: "one", p2: 1)
print(c1 == c2)

// 元组比较
// 会先比较第一个数，第一个无法比较才会比较第二个数
// 字符串比较和字母大小还有长度有关。先比较字母大小，再比较长度
("apple", 1) < ("apple", 2) // true
("applf", 1) < ("apple", 2) // false
("appl", 2) < ("apple", 1) // true
("appm", 2) < ("apple", 1) // false

// MARK:三元 _?_:_
// 简化 if else 写法

// if else
func f1(p: Int) {
    if p > 0 {
        print("positive number")
    } else {
        print("negative number")
    }
}

// 三元
func f2(p: Int) {
    p > 0 ? print("positive number") : print("negative number")
}

f1(p: 1)
f2(p: 1)

// MARK:Nil-coalescing??
// 简化 if let else 写法

// if else
func f3(p: Int?) {
    if let i = p {
        print("p have value is \(i)")
    } else {
        print("p is nil, use defalut value")
    }
}

// 使用 ??
func f4(p: Int?) {
    let i = p ?? 0
    print("p is \(i)")
}

f3(p: nil)
f4(p: nil)

// MARK:范围a…b
// 简化的值范围表达方式。

// 封闭范围
for i in 0...10 {
    print(i)
}

// 半开范围
for i in 0..<10 {
    print(i)
}
// 单侧区间
let nums = [5,6,7,8]
print(nums[2...]) // 7 8

// MARK:逻辑!,&&,||
let i1_1 = -1
let i2_1 = 2

if i1_1 != i2_1 && (i1_1 < 0 || i2_1 < 0) {
    print("i1 and i2 not equal, and one of them is negative number.")
}

// MARK:恒等===,!==
// 恒等返回是否引用了相同实例。

class C1 {
    var p: String
    init(p: String) {
        self.p = p
    }
}

let c1_1 = C1(p: "one")
let c2_1 = C1(p: "one")
let c3_1 = c1_1

print(c1_1 === c2_1) // false
print(c1_1 === c3_1) // true
print(c1_1 !== c2_1) // true

// MARK:运算符
// 位运算符

let i1_2: UInt8 = 0b00001111
let i2_2 = ~i1_2 // Bitwise NOT Operator（按位取反运算符），取反

let i3: UInt8 = 0b00111111
let i4 = i1_2 & i3 // Bitwise AND Operator（按位与运算符），都为1才是1
let i5 = i1_2 | i3 // Bitwise OR Operator（按位或运算符），有一个1就是1
let i6 = i1_2 ^ i3 // Bitwise XOR Operator（按位异或运算符），不同为1，相同为0

print(i1_2,i2_2,i3,i4,i5,i6)

// << 按位左移，>> 按位右移
let i7 = i1_2 << 1
let i8 = i1_2 >> 2
print(i7,i8)

//溢出运算符，有 &+、&- 和 &*

var i1_3 = Int.max
print(i1_3) // 9223372036854775807
i1_3 = i1_3 &+ 1
print(i1_3) // -9223372036854775808
i1_3 = i1_3 &+ 10
print(i1_3) // -9223372036854775798

var i2_3 = UInt.max
i2_3 = i2_3 &+ 1
print(i2_3) // 0

//运算符函数包括前缀运算符、后缀运算符、复合赋值运算符以及等价运算符。另，还可以自定义运算符，新的运算符要用 operator 关键字进行定义，同时要指定 prefix、infix 或者 postfix 修饰符。





